home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
byt87ibm.arc
/
INSERT.ASM
< prev
next >
Wrap
Assembly Source File
|
1980-01-05
|
10KB
|
302 lines
;---------------------------------------------------------------
; INSERT.ASM
;
; IN MICROSOFT MACRO ASSEMBLER SOURCE CODE
;
; PURPOSE:
; Insert data or blank columns into a text file. Not only
; string data, but the carriage return [CR], line feed [LF],
; and/or form feed [FF] characters can be inserted. Can be
; used with the pipe or redirection function.
;
; SYNTAX: INSERT /n/ [<"data string">] [CR] [FF] [LF] /
; Where n = column or character position to start the
; insert (255 max). CR = carriage return, LF = line feed,
; and FF = form feed.
;
; EXAMPLE: INSERT /1/"NEW DATA"CRLF/
; Would insert the words NEW DATA and then a carriage return
; and line feed at the beginning of each line of the input
; file. The result would be that NEW DATA would be
; inserted between each line of the input file.
;
; EXAMPLE: INSERT /9/CRLF/ < OLDDATA.TXT > NEWDATA.TXT
; Would insert CR and LF at position 9 on each line of the
; file OLDDATA.TXT and store it in a file named NEWDATA.TXT.
;
; <C> DEC. 1986 PAUL BAKER CLEVELAND TN
;---------------------------------------------------------------
PAGE ,132
dosint MACRO function ; call the DOS interrupt
MOV AH,function ; put function number in AH
INT 21h
ENDM
code SEGMENT byte public 'code'
ASSUME CS:CODE,DS:DATA,SS:STACK
ORG 0100H
STRT:
PUSH DS ; DO HOUSEKEEPING TO
SUB AX,AX ;ALLOW RETURN TO DOS
PUSH AX
MOV AX,DATA
MOV ES,AX ; set ES to top of data seg.
CLD
XOR CX,CX ; clear CX
MOV BX,CX ; clear BX
MOV SI,0080h ; point to PSP
LODSB ; find how many params
MOV CL,AL ; CL has count of params
CMP CL,00h ; if no params then show
JNZ not_zero ; use instructions.
MOV DX,OFFSET use_msg
PUSH ES
POP DS ; get local data segment.
dosint 09h ; display help screen.
IRET ; return to DOS.
not_zero: CMP CL,07h ; 7 is min. # of params.
JB bad_param ; if < 7 then error.
INC SI ; skip first space
LODSB ; see if / is present
CMP AL,2Fh
JNE bad_param ; if no / then error.
SUB CX,0002h ; adjust param count.
MOV DI,OFFSET strt_data ; set to top of buffer.
get_strt: LODSB ; load next param.
DEC CX
CMP AL,2Fh ; if / then must be end
JZ get_insert ; of first parameter
CMP CX,0000h ;
JBE bad_param ; if last param then leave.
CMP AL,30h ; if not a number between
JB bad_param ; 0 & 9 then exit
CMP AL,39h ; and give error
JG bad_param ; message.
INC BL ; bump digit count.
CMP BL,03h ; three digits max.
JG bad_param ; if more than 3 then error.
SUB AL,30h ; convert to binary.
CALL store_byte ; store each digit.
JMP get_strt ; get next param
get_insert: MOV DI,OFFSET insert_data ; load top of buffer
CMP BL,00h ; if no first param then
JLE bad_param ; send error message.
MOV BH,00h ; BH will count insert bytes.
LODSB ; get next param.
DEC CX ; reduce param count.
CMP AL,22h ; in quotes ?
JZ in_quotes ; if so then go process.
CMP AL,2Fh ; if another / then
JZ bad_param ; invalid parameter.
no_quotes: MOV AH,AL ; move low byte to high byte
LODSB ; load next byte.
DEC CX ; reduce param count.
CALL caps ; force upper case.
CMP AX,4352h ; if CR.
JZ cr
CMP AX,4C46h ; if LF.
JZ lf
CMP AX,4646h ; if FF.
JZ ff
JMP bad_param ; else must be error.
bad_param: MOV DX,OFFSET err1 ; point to error message
MOV CX,2Fh ; send 47 bytes.
MOV BX,0002h ; send to error output.
PUSH ES
POP DS ; get new data segment
dosint 40h ; display it
leave: IRET ; RETURN TO DOS
cr: MOV AL,0Dh ; load CR byte.
JMP put_insert
lf: MOV AL,0Ah ; load LF byte.
JMP put_insert
ff: MOV AL,0Ch ; load FF byte.
put_insert: CALL store_byte ; store insert info.
INC BH ; bump insert byte count.
LODSB ; get next param.
CMP AL,2Fh ; if / then must be end
JZ process ; of parameters.
CMP AL,22h ; if quotes then
JZ in_quotes ; is in quotes again.
JMP no_quotes ; else loop back.
in_quotes: LODSB
CMP AL,22h ; if " then out of quotes.
JNE in_quotes1 ; if not " then go on.
LODSB ; else get next after ".
CMP AL,2Fh ; if / then must be end
JZ process
JMP no_quotes
in_quotes1: CMP AL,2Fh ; if / then must be error
JZ bad_param ; since no closing ".
CALL store_byte ; store current byte.
INC BH ; bump insert byte count.
JMP in_quotes ; loop back.
;
; ----------- PROCESS INCOMING DATA -------------------
;
process:
PUSH ES ; load local data pointer.
POP DS
MOV insert_len,BH ; store insert length.
MOV digit_cnt,BL ; store digit count.
MOV AX,01h ; start AX @ 1
XOR CX,CX ; clear CX register.
MOV CL,digit_cnt ; load loop count.
loop1: MUL mult10 ; multiply by 10
LOOP loop1 ; create multiplier
MOV BX,AX ; save multiplier.
MOV CL,digit_cnt ; load loop count.
MOV SI,OFFSET strt_data ; point to 1'st digit
loop2: MOV AX,BX ; get multiplier.
DIV mult10 ;
MOV AH,00h ; clear remainder.
MOV BX,AX ; update multiplier.
MUL BYTE PTR [SI] ; multiply current digit.
ADD strt_col,AL ; update start col #.
INC SI ; bump pointer.
LOOP loop2
get_ready: XOR BX,BX ; load handle 00
dosint 45h ; get file duplicate.
MOV BP,AX ; set base pointer to handle.
dosint 3Eh ; close file.
; MOV BX,0002h ;
; dosint 45h ; file duplicate.
read_data: CLD
MOV DX,OFFSET data_buf ; store in data_buf
MOV CX,800h ; set to read 800h bytes.
MOV BX,BP ; set BX to file handle.
dosint 3Fh ; read input data.
OR AX,AX ; data read ?
JNZ more_data
no_data: IRET
more_data: MOV CX,AX ; CX has count of bytes read.
MOV SI,DX ; point to top of data.
get_byte: MOV BL,strt_col ; see if this is
CMP BL,col_cnt ; where the insert goes.
JNZ no_hit ; if not, then no hit.
CALL make_insert ; else make insert.
no_hit: LODSB ; get first byte.
CMP AL,1Ah ; if end of file, quit.
JZ no_data
CMP AL,0Dh ; cr ?
JNZ no_cr ; if not, go on.
MOV col_cnt,01h ; else reset column count.
MOV DL,AL ; send the CR
dosint 02h
DEC CX ; reduce byte count.
JMP no_hit ; get next byte.
no_cr: CMP AL,09h ; check for tab.
JNZ no_tab
CALL tab ; if so, call tab routin.
JMP get_byte ; loop back.
no_tab: CMP AL,1Fh ; do not count anything
JBE no_count ; else below 20h.
send_byte: INC col_cnt ; bump column count.
no_count: MOV DL,AL ; send byte to disply.
dosint 02h
DEC CX
go_back: JCXZ read_data
JMP get_byte
IRET
;
; ---------- MAKE INSERT ROUTINE ------------------------
;
make_insert: CMP insert_len,01h ; if nothing to insert
JB exit_insert ; then leave.
PUSH CX ; save CX and
PUSH SI ; and SI info.
MOV SI,OFFSET insert_data ; point to data.
XOR CX,CX ; load CX with
MOV CL,insert_len ; loop count.
insert_loop: LODSB ; load next byte.
MOV DL,AL
dosint 02h ; send byte out.
LOOP insert_loop
POP SI ; restore SI and
POP CX ; CX data.
exit_insert: RET
;
;---------------- TAB ROUTINE ---------------------------
;
tab: MOV CX,0008h ; expand tabs count.
MOV DL,20h ; load space byte.
tab_loop: CMP BL,col_cnt ; time to make insert ?
JNZ not_yet ;
CALL make_insert ; if so, then call insert.
MOV DL,20h ; reload space byte.
not_yet: dosint 02h ; send byte.
INC col_cnt ; bump column count.
LOOP tab_loop ; loop back.
RET
;
; --------------- CAPS ROUTINE --------------------------
;
caps: CMP AL,61h ; convert to
JB exit_caps ; all caps.
CMP AL,7Ah
JG exit_caps
AND AX,5F5Fh
exit_caps: RET
;
; ---------- STORE BYTE ROUTINE -----------------------------
;
store_byte: PUSH DS ; store current DS
PUSH ES ; local data segment info.
POP DS ; exchange them.
STOSB ; store local data.
PUSH DS
POP ES ; restore original
POP DS ; positions.
RET
CODE ENDS
;
; ------------ STACK SEGMENT -----------------------------
;
stack SEGMENT STACK 'stack'
DB 32 DUP(?)
stack ENDS
;
; ------------- DATA SEGMENT --------------------------------
;
data SEGMENT byte public 'DATA'
err1 DB 'INSERT : error - missing or invalid paramaters $'
strt_data DB 3h DUP (00h) ; start position as entered
strt_col DB 00 ; column to start insert
col_cnt DB 01h ; current column count.
digit_cnt DB 00h ; # of digits in 1'st param
insert_len DB 00h ; length of insert data string
insert_data DB 80h DUP(?) ; buffer for insert data
data_buf DB 800h DUP(?) ; buffer for input data.
mult10 DB 0Ah ; times 10 multiplier.
use_msg DB 13,10,'PURPOSE :',13,10,10
DB ' Insert data or blank columns into a '
DB 'text file. Not only string data, but',13,10
DB ' the Carriage Return [CR], Line Feed [LF] and/or'
DB ' Form Feed [FF] characters ',13,10
DB ' can be inserted. Can be used with the pipe or '
DB ' re-direction function.',13,10,10
DB 'SYNTAX : INSERT /n/ [<"data string">] [CR] [FF] [LF] /',13,10
DB 10,' Where n = column or character position'
DB ' to start the insert. (255 max.)',13,10
DB ' CR = Carriage Return, LF = Line Feed and FF = Form Feed'
DB 13,10,10,'EXAMPLE : INSERT /1/"NEW DATA"CRLF/',13,10,10
DB ' Would insert the words NEW DATA and then a carriage'
DB ' return and line feed ',13,10
DB ' at the begining of each line of the input file.'
DB 'The result would be that',13,10
DB ' NEW DATA would be inserted between each line'
DB ' of the input file.',10,13,10
DB 'EXAMPLE : INSERT /9/CRLF/ < OLDDATA.TXT > NEWDATA.TXT'
DB 13,10,10,' Would insert CR and LF at position 9 on each'
DB ' line of the file OLDDATA.TXT ',13,10
DB ' and store it in a disk file'
DB ' named NEWDATA.TXT.',13,10,10
DB ' <C> DEC. 1986 PAUL BAKER $'
data ENDS
END STRT
isk file'
DB ' named NEWDATA.TXT.',13,10,10
DB '